package com.barryredmond.mileagecalc;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.ItemStateListener;
import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.TextField;

public class MileageForm extends Form implements CommandListener, ItemStateListener{

    private final Settings settings = Settings.getSettings();
    
    private static final double MILES_PER_KILOMETERS = 0.621371192;
    private static final double US_GALLONS_PER_LITRE = 0.264172051; 
    private static final double IMPERIAL_GALLONS_PER_LITRE = 0.219969157;
    
    private final Command aboutCommand;
    private final Command exitCommand;
    private final Command settingsCommand;
    
    private final TextField kilometersBox;
    private final TextField milesBox;
    private final TextField litresBox;
    private final TextField gallonsBox;
    
    private final StringItem milesPerGallon;
    private final StringItem kilometersPerLitre;
    private final StringItem litresPer100Kilometers;
    

    public MileageForm() {
        super("Mileage Calculator");

        aboutCommand = new Command("About", Command.ITEM, 1);
        settingsCommand = new Command("Settings", Command.ITEM, 3);
        exitCommand = new Command("Exit", Command.BACK, 4);
        
        this.addCommand(aboutCommand);
        this.addCommand(settingsCommand);
        this.addCommand(exitCommand);
        this.setCommandListener(this);
        
        this.setItemStateListener(this);
        
        this.milesBox = new TextField("Miles", "0", 20, TextField.DECIMAL);
        this.kilometersBox = new TextField("Kilometers", "0", 20, TextField.DECIMAL);
        this.litresBox = new TextField("Litres", "0", 20, TextField.DECIMAL);
        this.gallonsBox = new TextField("Gallons", "0", 20, TextField.DECIMAL);
        
        this.milesPerGallon = new StringItem("Miles per Gallon", "NC");
        this.kilometersPerLitre = new StringItem("Kilometers per Litre", "NC");
        this.litresPer100Kilometers = new StringItem("Litres per 100Kilometers", "NC");
        
        this.refresh();
    }
    
    public void refresh(){
        this.deleteAll();
        if(settings.getBoolean(SettingsForm.SHOW_KILOMETERS, true)){
            this.append(kilometersBox);
        }
        if(settings.getBoolean(SettingsForm.SHOW_MILES, true)){
            this.append(milesBox);
        }
        if(settings.getBoolean(SettingsForm.SHOW_LITRES, true)){
            this.append(litresBox);
        }
        if(settings.getBoolean(SettingsForm.SHOW_GALLONS, true)){
        	gallonsBox.setLabel("Gallons (" + (settings.getBoolean(SettingsForm.USE_IMPERIAL, true)?"Imperial":"US") + ")");
            this.append(gallonsBox);
        }
        if(settings.getBoolean(SettingsForm.SHOW_LITRES_PER_100_KILOMETERS, true)){
        	this.append(litresPer100Kilometers);
        }
        if(settings.getBoolean(SettingsForm.SHOW_KILOMETERS_PER_LITRE, true)){
        	this.append(kilometersPerLitre);
        }
        if(settings.getBoolean(SettingsForm.SHOW_MILES_PER_GALLON, true)){
        	this.append(milesPerGallon);
        }
        
        this.calculate();
    }

    private void calculate(){
    	double litres, kilometers;
    	try{
    		litres = Double.parseDouble(litresBox.getString());
    	}catch(NumberFormatException e){
    		litres = 0;
    	}
    	try{
    		kilometers = Double.parseDouble(kilometersBox.getString());
    	}catch(NumberFormatException e){
    		kilometers = 0;
    	}
        try{
        	this.litresPer100Kilometers.setText("" + ((litres/kilometers)*100));
        }catch(ArithmeticException e){
        	this.litresPer100Kilometers.setText("0 Distance");
        }
                
        try{
            this.kilometersPerLitre.setText("" + (kilometers/litres));
        }catch(ArithmeticException e){
            this.kilometersPerLitre.setText("0 Fuel Volume");
            this.milesPerGallon.setText("0 Fuel Volume");
        }
        
        double gallons, miles;
        try{
        	gallons = Double.parseDouble(gallonsBox.getString());
        }catch(NumberFormatException e){
        	gallons = 0;
        }
        try{
        	miles = Double.parseDouble(milesBox.getString());
        }catch(NumberFormatException e){
        	miles = 0;
        }
        try{
            this.milesPerGallon.setText("" + (miles/gallons));
        }catch(ArithmeticException e){
            this.kilometersPerLitre.setText("0 Fuel Volume");
            this.milesPerGallon.setText("0 Fuel Volume");
        }
    }

    public void commandAction(Command command, Displayable displayable) {
        if(displayable == this){
            if(command == this.exitCommand){
                MileageMIDlet.getMileageMIDlet().notifyDestroyed();
            }else if(command == aboutCommand){
                gotoAboutScreen();
            }else if(command == settingsCommand){
                gotoSettingsScreen();
            }
        }
    }
    
    AboutScreen aboutScreen;
    private void gotoAboutScreen(){
        if(aboutScreen == null){
            aboutScreen = new AboutScreen(this);
        }
        Display.getDisplay(MileageMIDlet.getMileageMIDlet()).setCurrent(aboutScreen);
    }
    
    private SettingsForm settingsForm;
    private void gotoSettingsScreen(){
        if(settingsForm == null){
            settingsForm = new SettingsForm(this);
        }
        Display.getDisplay(MileageMIDlet.getMileageMIDlet()).setCurrent(settingsForm);
    }

    public void itemStateChanged(Item item) {
        final double gallons_per_litre;
        if(Settings.getSettings().getBoolean(SettingsForm.USE_IMPERIAL, true)){
            gallons_per_litre = IMPERIAL_GALLONS_PER_LITRE;
        }else{
            gallons_per_litre = US_GALLONS_PER_LITRE;
        }
        if(item == kilometersBox){
        	try{
        		final double miles = Double.parseDouble(kilometersBox.getString()) * MILES_PER_KILOMETERS;
                milesBox.setString("" + miles);
        	}catch(NumberFormatException e){
        		milesBox.setString("0");
        	}
            this.calculate();
        }else if(item == milesBox){
        	try{
	            final double kilometers = Double.parseDouble(milesBox.getString()) / MILES_PER_KILOMETERS;
	            kilometersBox.setString("" + kilometers);
        	}catch(NumberFormatException e){
        		kilometersBox.setString("0");
        	}
            this.calculate();
        }else if(item == litresBox){
        	try{
	            final double gallons = Double.parseDouble(litresBox.getString()) * gallons_per_litre;
	            gallonsBox.setString("" + gallons);
        	}catch(NumberFormatException e){
        		gallonsBox.setString("0");
        	}
            this.calculate();
        }else if(item == gallonsBox){
        	try{
	            final double litres = Double.parseDouble(gallonsBox.getString()) / gallons_per_litre;
	            litresBox.setString("" + litres);
        	}catch(NumberFormatException e){
        		litresBox.setString("0");
        	}
            this.calculate();
        }
    }

}
